#! /bin/sh
###############################################################################
#
#  EGSnrc script to finalize the installation of EGSnrc for a single user
#  Copyright (C) 2015 National Research Council Canada
#
#  This file is part of EGSnrc.
#
#  EGSnrc is free software: you can redistribute it and/or modify it under
#  the terms of the GNU Affero General Public License as published by the
#  Free Software Foundation, either version 3 of the License, or (at your
#  option) any later version.
#
#  EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#  FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
#  more details.
#
#  You should have received a copy of the GNU Affero General Public License
#  along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
#
#  Author:          Iwan Kawrakow, 2003
#
#  Contributors:    Dave Rogers
#                   Frederic Tessier
#                   Marc-Andre Renaud
#
###############################################################################
#
#  Short portions of this script are derived from configure scripts generated
#  by GNU autoconf (http://www.gnu.org/software/autoconf/).
#
#  Finalizes the installation of EGSnrc for the user executing the script.
#  Output is stored in log/finalize_$USER.log
#
#  1. Asks for a directory where all user codes are to be stored (EGS_HOME)
#     and creates it if needed.
#
#  2. Creates a PEGS4 area in EGS_HOME.
#
#  3. Defines useful environment variables and aliases in the user profile
#     (.cshrc or .bashrc or .profile, depending on the default shell for the
#     user, as specified by the $SHELL environment variable).
#
#  4. Compiles a set of user codes coming with the distribution.
#
###############################################################################


# my version
my_version='1.0'

# my name
my_dir=$(pwd)/$(dirname $0)
my_name=$(basename $0)

# printf format
format="%-50s"

# "none" and "help" inputs
none='--'
help='?'

# a timestamp
timestamp='Aug 25 2015'

# guess egs home location
if ! test "x$EGS_HOME" = x; then
    test_egs_home=$EGS_HOME
elif ! test "x$HEN_HOUSE" = x; then
    test_egs_home=$(dirname $HEN_HOUSE)/egs_home
else
    test_egs_home=$(cd $my_dir/../..; pwd)/egs_home
fi

cpp_user_codes="egs_app cavity egs_cbct egs_chamber egs_fac tutor2pp tutor7pp"
# Now explain to the user what this script is going to do.
#
cat >&2 <<_ACEOF

###############################################################################
$my_name
###############################################################################

Copyright (C) 2015 National Research Council Canada

This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you
are welcome to redistribute it under certain conditions. See LICENCE file for
details or http://www.gnu.org/licenses/agpl.txt

###############################################################################

You can exit this script at any time by typing Ctrl-C.

Press enter to continue.
_ACEOF

read response

exec 3>$my_dir/finalize_egs_$USER.log
cat >&3 <<EOF
###############################################################################
EGSnrc configuration for the user $USER
Generated by $my_name version $my_version $timestamp
###############################################################################

EOF

# select EGS_HOME directory
printf $format "EGS_HOME: " >&3
printf $format "Choose a directory for your user codes: " >&2
if test ! "x$test_egs_home" = x; then
  printf "[$test_egs_home] " >&2
fi

while true; do

    read response

    # default response
    if test "x$response" = x; then

        # egs_home suggestion
        if test "x$test_egs_home" = x; then
            echo "You must input a non empty string here!" >&2
        else
            response=$test_egs_home
            break
        fi

    # help
    elif test "x$response" = x$help; then
        cat >&2 <<_ACEOF

This directory is referred to as EGS_HOME. All EGSnrc user codes (the
user codes coming with the EGSnrc distribution and new user codes created
by you) are kept in separate subdirectories in EGS_HOME. User codes are
compiled and run from these subdirectories. The directory you specify
will be created for you in case it does not exist.

_ACEOF

    # user-specified path
    else
        # ensure this is an absolute path
        test_response=$( echo $response | sed 's,[\\/].*,,' )
        if test "x$test_response" = x; then
            break
        else
            echo "I'm expecting an absolute path here" >&2
        fi
    fi

    printf $format "Choose a directory for your user codes: " >&2
    if test ! "x$test_egs_home" = x; then
    printf "[$test_egs_home] " >&2
    fi
done

test_response=$( echo $response | sed 's,.*[\\/],,' )
if test "x$test_response" = x; then
    EGS_HOME="$response"
else
    EGS_HOME="$response/"
fi
echo $EGS_HOME >&3

printf $format "EGS_CONFIGURAION: " >&3
need_configuration=no
if test "x$EGS_CONFIG" = x; then
    need_configuration=yes
else
    hen_house=$( cat $EGS_CONFIG | grep "HEN_HOUSE =" | sed 's/HEN_HOUSE = //' )
    if test "x$hen_house" = x; then
        need_configuration=yes
    fi
fi

if test "x$need_configuration" = xyes; then

  printf $format "Input absolute path to EGSnrc configuration file: " >&2

  while true; do

    read response
    if test "x$response" = x || test "x$response" = x$help; then
      cat >&2 <<_ACEOF

The EGSnrc config file is found in the 'specs' subdirectory of the HEN_HOUSE,
inside your EGSnrc installation directory. It is automatically created during
the EGSnrc installation process and contains definitions such as HEN_HOUSE,
compiler name and options, etc.

_ACEOF
    else
      if test ! -f $response; then
        echo "The file $response does not exist" >&2
      else
        hen_house=$( cat $response | grep "HEN_HOUSE =" | sed 's/HEN_HOUSE = //' )
        if test "x$hen_house" = x; then
            echo "File $response is not a valid EGSnrc configuration file" >&2
        else
            break
        fi
      fi
    fi
    printf $format "Input absolute path to EGSnrc configuration file: " >&2

  done

  EGS_CONFIG="$response"
fi

HEN_HOUSE=$( cat $EGS_CONFIG | grep "HEN_HOUSE =" | sed 's/HEN_HOUSE = //' )
my_machine=$( cat $EGS_CONFIG | grep "my_machine =" | sed 's/my_machine = //' )
have_egspp_config=no
egspp_conf=$HEN_HOUSE/specs/egspp_${my_machine}.conf
if test -f $egspp_conf; then
    libext=$( cat $egspp_conf | grep "libext =" | sed 's/libext = //' )
    if test -f $HEN_HOUSE/egs++/dso/$my_machine/libegspp$libext; then
        have_egspp_config=yes
    fi
fi
OMEGA_HOME="${HEN_HOUSE}omega"

export EGS_CONFIG HEN_HOUSE OMEGA_HOME
echo "$EGS_CONFIG" >&3
printf $format "HEN_HOUSE:" >&3
echo "$HEN_HOUSE" >&3
printf $format "OMEGA_HOME:" >&3
echo "$OMEGA_HOME" >&3
echo >&3

echo >&2;
new_egs_home="no"
if test ! -d "$EGS_HOME"; then
    printf $format "Creating $(basename $EGS_HOME) ... " >&2
    printf $format "Creating $EGS_HOME ... " >&3
    mkdir $EGS_HOME || { echo "failed" >&2; echo "failed" >&3; exit 1; }
    echo "OK" >&2;
    echo "OK" >&3
    new_egs_home="yes"
fi

cd "$EGS_HOME" || { echo "Failed to cd to $EGS_HOME" >&2; exit 1; }
export EGS_HOME

for area in bin bin/$my_machine pegs4 pegs4/data pegs4/inputs pegs4/density beamnrc beamnrc/spec_modules; do

    if test ! -d $area; then
        printf $format "Creating $area directory ... " >&2
        printf $format "Creating $area directory ... " >&3
        mkdir $area || { echo "Failed" >&2; echo "Failed" >&3; exit 1; }
        echo "OK" >&2;
        echo "OK" >&3
    fi

done

# Copy all user codes to user area so that it is consistent with
# the install GUI and also don't need to fix egs_gui, which does not
# work if the user code is not on the user code area.
if test "x$new_egs_home" = xyes; then
    test_list=$( ls $HEN_HOUSE/user_codes )
    copy_list=
    for uc in $test_list; do
        if test -d $HEN_HOUSE/user_codes/$uc && test $uc != pegs4 && test $uc != bin; then
            copy_list="$copy_list $uc"
        fi
    done
    echo >&2;
    echo "Copying user codes to EGS_HOME area ..." >&2
    echo "Copying user codes to EGS_HOME area" >&3
    for uc in $copy_list; do
        printf $format "    Copying $uc ..." >&2
        cp -r $HEN_HOUSE/user_codes/$uc .
        echo "OK" >&2
    done

    # Copy BEAMnrc examples .module files to user area
    test_list=$( ls $OMEGA_HOME/beamnrc/BEAMnrc_examples/ )
    copy_list=
    for uc in $test_list; do
        if test -f $OMEGA_HOME/beamnrc/BEAMnrc_examples/$uc/$uc.module; then
            copy_list="$copy_list $uc"
        fi
    done
    echo >&2;
    echo "Copying BEAMnrc examples .module files ..." >&2
    echo "Copying BEAMnrc examples .module files ..." >&3
    for uc in $copy_list; do
        printf $format "    Copying $uc.module ..." >&2
        cp -r $OMEGA_HOME/beamnrc/BEAMnrc_examples/$uc/$uc.module ./beamnrc/spec_modules
        echo "OK" >&2
    done
fi


echo "" >&2
echo "You may now compile user codes. Please select:" >&2
echo "    1. Compile all" >&2
echo "    2. Compile selected" >&2
echo "    3. Compile none (default)" >&2
echo >&2
printf $format "Choose 1 (all), 2 (some) or 3 (none): " >&2
printf "[3] " >&2
printf "Compilation selection: " >&3
read response
echo "$response" >&3

if test "x$response" = x1; then
    test_list=$( ls $HEN_HOUSE/user_codes )
    compile_list=
    for uc in $test_list; do
        if test -d $HEN_HOUSE/user_codes/$uc && test -d $EGS_HOME/$uc; then
            compile_list="$compile_list $uc"
        fi
    done
elif test "x$response" = x2; then
    printf $format "Input a list of user codes to compile or <enter> for a list: "
    read test_list
    if test "x$test_list" = x; then
      junk_list=$( ls $HEN_HOUSE/user_codes )
      junk_compile_list=
      for uc in $junk_list; do
          if test -d $HEN_HOUSE/user_codes/$uc && test -d $EGS_HOME/$uc; then
              junk_compile_list=$( printf "$junk_compile_list\n$uc" )
          fi
      done
      echo "Available user codes are: " >&2
      echo "$junk_compile_list" | sed "/^ *$/d" | sed "s/^/    /" >&2
      printf $format "Input a list of user codes to compile " >&2
      read test_list
    fi
    compile_list=
    for uc in $test_list; do
        if test -d $HEN_HOUSE/user_codes/$uc && test -d $EGS_HOME/$uc; then
            compile_list="$compile_list $uc"
        fi
    done
else
    compile_list=
fi
echo "Compilation list: $compile_list" >&3

for uc in $compile_list; do
    printf $format "    Compiling $uc ..." >&2
    echo "*************** Compiling $uc ****************** " >&3
    do_it=yes
    if test $have_egspp_config = no; then
        for egspp_app in $cpp_user_codes; do
            if test $egspp_app = $uc; then
                do_it=no
                break
            fi
        done
    fi
    if test $do_it = yes; then
    if { $HEN_HOUSE/scripts/compile_user_code mf $uc >&3 2>&3; mystatus=$?;
         (exit $mystatus;); } then
        echo "OK" >&2; echo "OK" >&3
    else
        echo "failed" >&2; echo "failed" >&3
    fi
    else
        echo "Skipping (no egs++ installation)" >&2
        echo "Skipping (no egs++ installation)" >&3
    fi
done

# move configuration log to log directory
if test -f $my_dir/finalize_egs_$USER.log && test -d $HEN_HOUSE/log; then
    mv $my_dir/finalize_egs_$USER.log $HEN_HOUSE/log/configure-$my_machine-$USER.log
    echo >&2
    printf $format "EGSnrc user configuration log saved in:" >&2
    echo >&2
    echo "$HEN_HOUSE/log/configure-$my_machine-$USER.log" >&2
fi

cat >&2 <<EOF

###############################################################################

The EGSnrc configuration for $USER is ALMOST complete ...

EGSnrc requires various environment variables and aliases to be defined.
Typically you add these definitions to your shell resource file located in
your home directory, to ensure the EGSnrc environment is properly set up
every time you log in.

EOF

# check if system is darwin
canonical_system=$( cat $EGS_CONFIG | grep "canonical_system =" | sed 's/canonical_system = //' )
is_darwin=$(echo $canonical_system | grep -i darwin)

# prescribe lines to add to shell resource file
echo "Your default shell is $SHELL" >&2
test_shell=$( echo $SHELL | sed 's,.*[\\/],,' )
if test "x$test_shell" = xtcsh || test "x$test_shell" = xcsh; then
  echo "Add the following statements to your .cshrc file: " >&2
  echo >&2
  echo "setenv EGS_HOME $EGS_HOME" >&2
  echo "setenv EGS_CONFIG $EGS_CONFIG" >&2
  echo "source ${HEN_HOUSE}scripts/egsnrc_cshrc_additions" >&2
elif test "x$test_shell" = xksh || test "x$test_shell" = xsh; then
  echo "Add the following statements to your .profile file: " >&2
  echo >&2
  echo "EGS_HOME=$EGS_HOME" >&2
  echo "EGS_CONFIG=$EGS_CONFIG" >&2
  echo "export EGS_HOME EGS_CONFIG" >&2
  echo "source ${HEN_HOUSE}scripts/egsnrc_bashrc_additions" >&2
elif test ! "x$is_darwin" = x; then
  echo "Add the following statements to your .profile file: " >&2
  echo >&2
  echo "export EGS_HOME=$EGS_HOME" >&2
  echo "export EGS_CONFIG=$EGS_CONFIG" >&2
  echo "source ${HEN_HOUSE}scripts/egsnrc_bashrc_additions" >&2
elif test "x$test_shell" = xbash; then
  echo "Add the following statements to your .bashrc file: " >&2
  echo >&2
  echo "export EGS_HOME=$EGS_HOME" >&2
  echo "export EGS_CONFIG=$EGS_CONFIG" >&2
  echo "source ${HEN_HOUSE}scripts/egsnrc_bashrc_additions" >&2
elif test "x$test_shell" = xfish; then
  echo "Add the following statements to your .config/fish/config file: " >&2
  echo >&2
  echo "set -x EGS_HOME $EGS_HOME" >&2
  echo "set -x EGS_CONFIG $EGS_CONFIG" >&2
  echo "source ${HEN_HOUSE}scripts/egsnrc_fishrc_additions" >&2
else
  cat >&2 <<EOF
Could not determine your default shell type. To make use of the EGSnrc
system it is advantageous to define environment variables and aliases in
the file that is run each time you open a new shell. Depending on your
shell type, this file may be .cshrc, .bashrc, .profile, .login, etc.,
in your home directory. Please ask your system administrator which
resource file appropriate. Add the following lines at the end of this
shell resource file:

If your default shell is a C shell or derivative, add:

setenv EGS_HOME $EGS_HOME
setenv EGS_CONFIG $EGS_CONFIG
source ${HEN_HOUSE}scripts/egsnrc_cshrc_additions

if your default shell is a Bourne shell or derivative, add:

EGS_HOME=$EGS_HOME
EGS_CONFIG=$EGS_CONFIG
export EGS_HOME EGS_CONFIG
source ${HEN_HOUSE}scripts/egsnrc_bashrc_additions

EOF
fi

cat >&2 <<EOF

###############################################################################

EOF

exit 0
